package org.shopen.puremvc.model
{
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.mxml.HTTPService;
	
	import org.puremvc.as3.interfaces.IProxy;
	import org.puremvc.as3.patterns.proxy.Proxy;
	import org.shopen.puremvc.ApplicationParameters;
	import org.shopen.puremvc.model.domain.OrganizationMeta;
	import org.shopen.puremvc.model.utils.CompleteDelegate;

	public class ManifestProxy extends Proxy implements IProxy, IService
	{
		public static const NAME : String = "ManifestProxy";
		public static const MANIFEST_LOADED : String = NAME + "." + "MANIFEST_LOADED";
		public static const MANIFEST_LOAD_FAILED : String = NAME + "." + "MANIFEST_LOAD_FAILED";
		public static const ORGANIZATION_META_AVAILABLE : String = NAME + "." + "ORGANIZATION_META_AVAILABLE";
		
		private var _service : HTTPService;
		protected function get service() : HTTPService
		{
			return _service;
		}
		protected function set service(value : HTTPService) : void
		{
			_service = value;
		}
		
		protected var completeDelegate : CompleteDelegate = null;
		
		override public function getProxyName():String
		{
			return NAME;
		}
		
		public function get organizationMeta() : OrganizationMeta
		{
			var result : OrganizationMeta = new OrganizationMeta(manifestXML);
			return result;
		}
		
		public function get manifestXML() : XML
		{
			return data as XML;
		}
		
		public function get readingXML() : XML
		{
			var result : XML = null;
			if (manifestXML != null)
			{
				result = manifestXML.reading[0];
			}
			return result;
		}
		
		public function get testingsXML() : XML
		{
			var result : XML = null;
			if (manifestXML != null)
			{
				result = manifestXML.testings[0];
			}
			return result;
		}
		
		public function ManifestProxy()
		{
			super(NAME);			
		}
		
		override public function onRegister():void
		{
			setService();
		}
			
		private function setService() : void
		{
			service = new HTTPService();
			service.url = ApplicationParameters.MANIFEST_PATH;
			service.resultFormat = "e4x";
			service.addEventListener(ResultEvent.RESULT, serviceResultListener);
			service.addEventListener(FaultEvent.FAULT, serviceFaultListener);
		}
		
		private function serviceResultListener(event : ResultEvent) : void
		{
			var dataXML : XML = event.result as XML;
			setData(dataXML);
			sendResult();
			sendCompleteEvent();
		}
		
		private function sendResult() : void
		{
			sendNotification(ManifestProxy.MANIFEST_LOADED, manifestXML);
			sendNotification(ManifestProxy.ORGANIZATION_META_AVAILABLE, organizationMeta);
		}
		
		private function serviceFaultListener(event : FaultEvent) : void
		{
			sendNotification(ManifestProxy.MANIFEST_LOAD_FAILED, event.message.toString());
		}
		
		private function sendCompleteEvent() : void
		{
			if (completeDelegate != null)
			{
				completeDelegate.dispatchComplete();
			}
		}
		
		public function loadData(completeDelegate : CompleteDelegate = null) : void
		{
			this.completeDelegate = completeDelegate;
			if (isDataLoaded)
			{
				sendResult();
				sendCompleteEvent();
			}
			else
			{
				service.send();
			}
		}
		
		public function get isDataLoaded() : Boolean
		{
			var result : Boolean = getData() != null;
			return result;
		}
	}
}